/**
 * Treatmentrecordscreen class
 */
package com.frontend.screens;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.Insets;
import java.util.Calendar;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import com.data.documents.DoctorsOrder;
import com.data.documents.Invoice;
import com.data.documents.TreatmentRecord;
import com.frontend.ConnectionException;
import com.frontend.DoctorsOfficeClient;
import com.users.User;
import com.util.*;

/**
 * The Class TreatmentRecordScreen.
 */
public class TreatmentRecordScreen extends Screen {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -1137077503774930852L;

	/** The doctors order label. */
	private JLabel message, dateLabel, timeLabel, attendingDocLabel,
			attendingNurseLabel, bloodPressureLabel, pulseLabel, tempLabel,
			patientHeightLabel, weightLabel, chiefComplaintLabel,
			diagnosisLabel;

	/** The diagnosis. */
	private JTextField bloodPressure, pulse, temp, patientHeight, weight,
			chiefComplaint, diagnosis;

	private JComboBox attendingDoc, attendingNurse, year, month, day, time;

	/** The b11. */
	private JPanel b0, b1, b12, mainPanel;

	/** The back. */
	private JButton doctorsOrders, submit, back, invoice;

	/** The block. */
	boolean fadeout, fadein, block;

	/** The timer. */
	javax.swing.Timer timer;

	/** The cycles. */
	int cycles;

	private TreatmentRecord tr;

	private User u;

	private Screen prevScreen;

	private String[] doctors, nurses, times;

	private Calendar calendar;

	/**
	 * Instantiates a new treatment record screen.
	 * 
	 * @param window
	 *            the window
	 */
	public TreatmentRecordScreen(DoctorsOfficeClient window,
			TreatmentRecord tr, User u, Screen prevScreen) {
		super(window);
		this.prevScreen = prevScreen;
		this.tr = tr;
		this.u = u;

		times = getTimesArray();
		calendar = Calendar.getInstance();
		if (tr.getDateTime() != 0)
			calendar.setTimeInMillis(tr.getDateTime());

		timer = new javax.swing.Timer(50, new AnimationListener());
		block = true;

		setLayout(null);
		TreatmentRecordListener trl = new TreatmentRecordListener(this);

		b0 = new JPanel();
		b0.setOpaque(false);

		message = new JLabel("Treatment Record");

		b1 = new JPanel();
		b1.setOpaque(false);

		dateLabel = new JLabel("Date: ");
		dateLabel.setHorizontalAlignment(SwingConstants.TRAILING);

		DateItemListener dil = new DateItemListener();

		int currentYear = calendar.get(Calendar.YEAR);
		Integer[] years = new Integer[100];
		for (int i = 0; i < 100; i++) {
			years[i] = currentYear + i - 50;
		}
		year = new JComboBox(years);
		year.setSelectedItem(new Integer(currentYear));
		year.addItemListener(dil);

		int currentMonth = calendar.get(Calendar.MONTH);
		String[] monthList = getMonthStrings();
		month = new JComboBox(monthList);
		month.setSelectedIndex(currentMonth);
		month.addItemListener(dil);

		int numDays = DaysCount.daysIn(currentMonth, currentYear);
		Integer[] days = new Integer[numDays];
		for (int i = 0; i < numDays; i++) {
			days[i] = i + 1;
		}
		int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
		day = new JComboBox(days);
		day.setSelectedIndex(currentDay - 1);

		timeLabel = new JLabel("Time :");
		timeLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		time = new JComboBox(times);
		int index = (calendar.get(Calendar.HOUR_OF_DAY)) * 2;
		if (calendar.get(Calendar.MINUTE) != 0)
			index++;
		time.setSelectedIndex(index);

		try {
			doctors = window.getNet().listUsersNames(User.DOCTOR);
		} catch (ConnectionException e) {
			System.out.println(e.getMessage());
		}

		attendingDocLabel = new JLabel("Attending Doctor :");
		attendingDocLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		attendingDoc = new JComboBox(doctors);
		attendingDoc.addActionListener(trl);

		try {
			nurses = window.getNet().listUsersNames(User.NURSE);
		} catch (ConnectionException e) {
			System.out.println(e.getMessage());
		}

		attendingNurseLabel = new JLabel("Attending Nurse :");
		attendingNurseLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		attendingNurse = new JComboBox(nurses);

		bloodPressureLabel = new JLabel("Blood Pressure :");
		bloodPressureLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		bloodPressure = new JTextField();
		bloodPressure.addActionListener(trl);

		pulseLabel = new JLabel("Pulse :");
		pulseLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		pulse = new JTextField();
		pulse.addActionListener(trl);

		tempLabel = new JLabel("Temperature :");
		tempLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		temp = new JTextField();
		temp.addActionListener(trl);

		patientHeightLabel = new JLabel("Height :");
		patientHeightLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		patientHeight = new JTextField();
		patientHeight.addActionListener(trl);

		weightLabel = new JLabel("Weight :");
		weightLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		weight = new JTextField();
		weight.addActionListener(trl);

		chiefComplaintLabel = new JLabel("Chief Complaint :");
		chiefComplaintLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		chiefComplaint = new JTextField();
		chiefComplaint.addActionListener(trl);

		diagnosisLabel = new JLabel("Diagnosis :");
		diagnosisLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		diagnosis = new JTextField();
		diagnosis.addActionListener(trl);

		b12 = new JPanel();
		b12.setOpaque(false);

		submit = new JButton("Submit");
		submit.setOpaque(false);
		submit.addActionListener(trl);
		back = new JButton("Back");
		back.setOpaque(false);
		back.addActionListener(trl);
		invoice = new JButton("Create/Edit Invoice");
		invoice.setOpaque(false);
		invoice.addActionListener(trl);
		doctorsOrders = new JButton("Add/Edit Doctors Order");
		doctorsOrders.setAlignmentX(CENTER_ALIGNMENT);
		doctorsOrders.addActionListener(trl);

		if (tr.getAttendingDoctor() != null)
			attendingDoc.setSelectedItem(tr.getAttendingDoctor().getName());
		if (tr.getAttendingNurse() != null)
			attendingNurse.setSelectedItem(tr.getAttendingNurse().getName());
		bloodPressure.setText(Double.toString(tr.getBloodPressure()));
		pulse.setText(Double.toString(tr.getPulse()));
		temp.setText(Double.toString(tr.getTemperature()));
		patientHeight.setText(Double.toString(tr.getHeight()));
		weight.setText(Double.toString(tr.getWeight()));
		chiefComplaint.setText(tr.getChiefComplaint());
		diagnosis.setText(tr.getDiagnosis());

		add(dateLabel);
		add(year);
		add(month);
		add(day);

		mainPanel = new JPanel();
		mainPanel.setOpaque(false);
		mainPanel.setLayout(new GridLayout(10, 2, 0, 3));
		mainPanel.add(timeLabel);
		mainPanel.add(time);
		mainPanel.add(attendingDocLabel);
		mainPanel.add(attendingDoc);
		mainPanel.add(attendingNurseLabel);
		mainPanel.add(attendingNurse);
		mainPanel.add(bloodPressureLabel);
		mainPanel.add(bloodPressure);
		mainPanel.add(pulseLabel);
		mainPanel.add(pulse);
		mainPanel.add(tempLabel);
		mainPanel.add(temp);
		mainPanel.add(patientHeightLabel);
		mainPanel.add(patientHeight);
		mainPanel.add(weightLabel);
		mainPanel.add(weight);
		mainPanel.add(chiefComplaintLabel);
		mainPanel.add(chiefComplaint);
		mainPanel.add(diagnosisLabel);
		mainPanel.add(diagnosis);

		JPanel mainPanelHolder = new JPanel();
		mainPanelHolder.setOpaque(false);
		mainPanelHolder.add(mainPanel);

		message.setHorizontalAlignment(SwingConstants.CENTER);

		add(b0);
		add(message);
		add(b1);
		// add(datePanel);
		// add(b2);
		// add(timePanel);
		// add(b3);
		// add(attendingDocPanel);
		// add(b4);
		// add(attendingNursePanel);
		// add(b5);
		// add(bloodPressurePanel);
		// add(b6);
		// add(pulsePanel);
		// add(b7);
		// add(tempPanel);
		// add(b8);
		// add(heightPanel);
		// add(b9);
		// add(weightPanel);
		// add(b10);
		// add(chiefComplaintPanel);
		// add(b11);
		// add(diagnosisPanel);
		// add(mainPanelHolder);
		add(mainPanel);
		add(b12);
		if (window.getCurrentUser().getUser_type() == User.DOCTOR) {
			add(doctorsOrders);
		}
		add(invoice);
		add(submit);
		add(back);
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (getHeight() != tempheight || getWidth() != tempwidth) {
			int width = getWidth();
			int height = getHeight();
			Insets insets = getInsets();
			int curY = height / 60 + insets.top;
			FontMetrics fm = g.getFontMetrics(new Font("Arial", Font.BOLD,
					getHeight() / 15));
			int textWidth = (int) fm.getStringBounds(message.getText(), g)
					.getWidth();

			message.setFont(new Font("Arial", Font.BOLD, getHeight() / 15));
			message.setBounds(width / 2 + insets.left - textWidth / 2, curY,
					textWidth, height / 15);
			curY += height / 15;
			curY += height / 60;

			dateLabel.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			dateLabel.setBounds(width / 2 + insets.left - textWidth/2 - width / 5, curY, width / 5, height / 25);
			month.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			month.setBounds(width / 2 + insets.left - textWidth/2,
					curY, width * 2 / 15, height / 25);
			day.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			day.setBounds(width / 2 + insets.left - textWidth/2 + 2 * width / 15, curY,
					width * 2 / 15, height / 25);
			year.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			year.setBounds(width / 2 + insets.left - textWidth/2 + 4 * width / 15, curY, width * 2 / 15, height / 25);

			curY += height / 25;
			curY += height / 60;

			timeLabel.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			time.setMaximumSize(new Dimension(getWidth() / 2, getHeight() / 25));
			time.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));

			mainPanel.setBounds(width / 2 - textWidth / 2 - width * 2 / 5
					+ insets.left, curY, width * 4 / 5, height * 3 / 4 - height
					* 3 / 44);
			mainPanel.setLayout(new GridLayout(11, 2, 0, getHeight() / 60));

			curY += height * 3 / 4 - height * 3 / 44;

			timeLabel.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			time.setMaximumSize(new Dimension(getWidth() / 2, getHeight() / 25));
			time.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			attendingNurseLabel.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			attendingNurse.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			attendingNurse.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			attendingDocLabel.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			attendingDoc.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			attendingDoc
					.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			bloodPressureLabel.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			bloodPressure.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			bloodPressure.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			pulseLabel.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			pulse.setMaximumSize(new Dimension(getWidth() / 2, getHeight() / 25));
			pulse.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			tempLabel.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			temp.setMaximumSize(new Dimension(getWidth() / 2, getHeight() / 25));
			temp.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			patientHeightLabel.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			patientHeight.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			patientHeight.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			weightLabel
					.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			weight.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			weight.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));
			chiefComplaintLabel.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			chiefComplaint.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			chiefComplaint.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			diagnosisLabel.setFont(new Font("Arial", Font.PLAIN,
					getHeight() / 30));
			diagnosis.setMaximumSize(new Dimension(getWidth() / 2,
					getHeight() / 25));
			diagnosis.setFont(new Font("Arial", Font.PLAIN, getHeight() / 30));

			curY += height / 60;

			if (window.getCurrentUser().getUser_type() == User.DOCTOR) {
				doctorsOrders.setMaximumSize(new Dimension(getWidth() / 2,
						getHeight() / 20));
				doctorsOrders.setFont(new Font("Arial", Font.PLAIN,
						getHeight() / 25));
				doctorsOrders.setBounds(width / 2 + insets.left - 2 * width / 5
						- width / 30, curY, 2 * width / 5, height / 20);

				invoice.setMaximumSize(new Dimension(getWidth() / 2,
						getHeight() / 20));
				invoice.setFont(new Font("Arial", Font.PLAIN, getHeight() / 25));
				invoice.setBounds(width / 2 + insets.left + width / 30, curY,
						2 * width / 5, height / 20);
			} else {
				invoice.setMaximumSize(new Dimension(getWidth() / 2,
						getHeight() / 20));
				invoice.setFont(new Font("Arial", Font.PLAIN, getHeight() / 25));
				invoice.setBounds(width / 2 + insets.left - width / 5, curY,
						2 * width / 5, height / 20);
			}
			curY += height / 20;
			curY += height / 60;

			submit.setMaximumSize(new Dimension(getWidth() / 5,
					getHeight() / 15));
			submit.setFont(new Font("Arial", Font.PLAIN, getHeight() / 25));
			submit.setBounds(width / 2 + insets.left - width / 5, curY, width
					/ 5 - width / 60, height / 20);

			back.setMaximumSize(new Dimension(getWidth() / 5, getHeight() / 15));
			back.setFont(new Font("Arial", Font.PLAIN, getHeight() / 25));
			back.setBounds(width / 2 + insets.left + width / 60, curY, width
					/ 5 - width / 60, height / 20);

			tempheight = getHeight();
			tempwidth = getWidth();
		}
	}

	/**
	 * The listener interface for receiving appointment events. The class that
	 * is interested in processing a appointment event implements this
	 * interface, and the object created with that class is registered with a
	 * component using the component's
	 * <code>addAppointmentListener<code> method. When
	 * the appointment event occurs, that object's appropriate
	 * method is invoked.
	 * 
	 * @see AppointmentEvent
	 */
	private class TreatmentRecordListener implements ActionListener {

		private Screen superClass;

		public TreatmentRecordListener(Screen superClass) {
			super();
			this.superClass = superClass;
		}

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == back) {
				window.changeScreen(prevScreen);
				prevScreen.repaint();
				if (prevScreen instanceof PatientOverviewScreen) {
					((PatientOverviewScreen) prevScreen).search();
				}
			} else if (e.getSource() == doctorsOrders) {
				//if this treatment record doesn't have a doctors order yet, make one
				if(tr.getDoctorsOrder() == null){
					try {
						window.getNet().updateDocument(tr, u.getUsername());
						DoctorsOrder dO = new DoctorsOrder(window.getNet().generateDocId());
						window.getNet().addDocument(dO, u.getUsername());
						tr.setDoctorsOrder(dO);
					} catch (ConnectionException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				//go to the doctors oder screen
				window.changeScreen(new DoctorsOrderScreen(window, tr
						.getDoctorsOrder(), u, tr, superClass));
			} else if (e.getSource() == invoice) {
				if(tr.getInvoice() == null){
					try {
						window.getNet().updateDocument(tr, u.getUsername());
						Invoice inv = new Invoice(window.getNet().generateDocId());
						window.getNet().addDocument(inv, u.getUsername());
						tr.setInvoice(inv);
						System.out.println("invoice made and added");
					} catch (ConnectionException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}				
				window.changeScreen(new CreateInvoiceScreen(window, tr.getInvoice(), u, tr, superClass));
			} else {
				
				int yr = (Integer) year.getSelectedItem();
				int mnth = month.getSelectedIndex();
				int d = day.getSelectedIndex() + 1;
				String t = (String) time.getSelectedItem();
				int hr = Integer.parseInt(t.split(":")[0]);
				int min = Integer.parseInt(t.split(":")[1]);
				calendar.set(yr, mnth, d, hr, min);
				tr.setDateTime(calendar.getTimeInMillis());
				//if the invoice exists, set its date to the date of the doctors order
				if(tr.getInvoice() != null)
					System.out.println("added date to the invoice");
					tr.getInvoice().setDate(calendar.getTimeInMillis());
				try {
					tr.setAttendingDoctor(window.getNet().getUser(
							((String) attendingDoc.getSelectedItem()),
							User.DOCTOR));
				} catch (ConnectionException e1) {
					System.out.println(e1.getMessage());
				}
				try {
					tr.setAttendingNurse(window.getNet().getUser(
							((String) attendingNurse.getSelectedItem()),
							User.NURSE));
				} catch (ConnectionException e1) {
					System.out.println(e1.getMessage());
				}
				tr.setBloodPressure(Double.parseDouble(bloodPressure.getText()));
				tr.setPulse(Double.parseDouble(pulse.getText()));
				tr.setTemperature(Double.parseDouble(temp.getText()));
				tr.setHeight(Double.parseDouble(patientHeight.getText()));
				tr.setWeight(Double.parseDouble(weight.getText()));
				tr.setChiefComplaint(chiefComplaint.getText());
				tr.setDiagnosis(diagnosis.getText());

				block = false;

				if (bloodPressure.getText().equals("")
						&& pulse.getText().equals("")
						&& temp.getText().equals("")
						&& patientHeight.getText().equals("")
						&& weight.getText().equals("")
						&& chiefComplaint.getText().equals("")
						&& diagnosis.getText().equals("")) {
					timer.stop();
					block = true;
					fadeout = true;
					cycles = 0;
					message.setText("Atleast one field must be filled in.");
					message.setForeground(Color.red);
					timer.start();
				}

				if (!block) {
					try {
						if(tr.getDoctorsOrder() != null)
							window.getNet().updateDocument(tr.getDoctorsOrder(),
								u.getUsername());
						if(tr.getInvoice() != null){
							tr.getInvoice().setDate(tr.getDateTime());
							window.getNet().updateDocument(tr.getInvoice(), u.getUsername());
						}
						window.getNet().updateDocument(tr, u.getUsername());
					} catch (ConnectionException e1) {
						e1.printStackTrace();
					}
					timer.stop();
					block = true;
					fadeout = true;
					cycles = 0;
					message.setText("Treatment Record Submitted!");
					message.setForeground(Color.red);
					timer.start();
				}
			}
		}
	}

	private class DateItemListener implements ItemListener {

		@Override
		public void itemStateChanged(ItemEvent arg0) {
			int currentMonth = month.getSelectedIndex();
			int currentYear = (Integer) year.getSelectedItem();
			int currentDay = (Integer) day.getSelectedItem();
			int numDays = DaysCount.daysIn(currentMonth, currentYear);
			if (currentDay > numDays)
				currentDay = numDays;
			day.removeAllItems();
			for (int i = 0; i < numDays; i++) {
				day.insertItemAt((Integer) (i + 1), i);
			}
			day.setSelectedIndex(currentDay - 1);
			revalidate();
			repaint();
		}

	}

	/**
	 * The listener interface for receiving animation events. The class that is
	 * interested in processing a animation event implements this interface, and
	 * the object created with that class is registered with a component using
	 * the component's <code>addAnimationListener<code> method. When
	 * the animation event occurs, that object's appropriate
	 * method is invoked.
	 * 
	 * @see AnimationEvent
	 */
	private class AnimationListener implements ActionListener {

		/** The alpha val. */
		private int alphaVal;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent
		 * )
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			if (cycles == 0)
				alphaVal = 255;
			cycles++;

			if (cycles > 20) {
				if (fadeout) {
					alphaVal = alphaVal - 10;
					if (alphaVal < 0)
						alphaVal = 0;
					message.setForeground(new Color(255, 0, 0, alphaVal));
					if (alphaVal == 0) {
						fadeout = false;
						fadein = true;
						message.setText("Make an Appointment");
					}
				}
				if (fadein) {
					alphaVal += 10;
					if (alphaVal > 255)
						alphaVal = 255;
					message.setForeground(new Color(0, 0, 0, alphaVal));
					if (alphaVal == 255) {
						fadein = false;
						timer.stop();
					}
				}
			}
		}

	}

}
